package com.ljx.reflect.reflect01;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.lang.annotation.Annotation;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;

/**
 * @author LJX
 * @Description: TODO
 * @Date: 2022/10/25 21:09
 * @Version 1.0
 */
public class Test01 {
	public static void main(String[] args) throws Exception{
		// 1通过类名获取反射机制
		Class ljxClass = Ljx.class;
		// getField只能获取到声明修饰符为public的属性 并且是指定的属性
		Field name = ljxClass.getField("age");
		System.out.println(name);
		// getFields只能获取到声明修饰符为public的全部属性
		Field[] fields = ljxClass.getFields();
		for (Field field : fields) {
			System.out.println(field);
		}

		System.out.println("------------------------------------------");
		// 获取指定的成员变量属性(都可以获取到)
		Field weight = ljxClass.getDeclaredField("weight");
		System.out.println(weight);
		// 获取全部的成员变量属性(都可以获取到)
		Field[] declaredFields = ljxClass.getDeclaredFields();
		for (Field declaredField : declaredFields) {
			System.out.println(declaredField);
		}


		System.out.println("~~~~~~~~~~~~~~~~");
		// 获取构造方法
		Constructor declaredConstructor = ljxClass.getDeclaredConstructor();
		System.out.println(declaredConstructor);
		// 获取所有的构造方法
		Constructor[] declaredConstructors = ljxClass.getDeclaredConstructors();
		for (Constructor constructor : declaredConstructors) {
			System.out.println(constructor);
		}


		System.out.println("+++++++++++++++++++++++++++++");
		// 获取注解
//		Annotation annotation = ljxClass.getAnnotation(Ljx.class);
//		System.out.println(annotation);
		Annotation[] annotations = ljxClass.getAnnotations();
		for (Annotation annotation1 : annotations) {
			System.out.println(annotation1);
		}


		// 反射获取方法
		// 通过类名获取
		/*
		* newInstance() 方法
		  通过Class 类的newInstance()方法创建对象,
		  该方法要求该 Class 对应类有无参构造方法。
		  执行newInstance()方法实际上就是使用对应类的无参构造方法来创建该类的实例,
		  其代码的作用等价于Super sup = new Super()。*/
		Object o = ljxClass.newInstance();
		System.out.println(o);
		// 获取所有本类中定义的method方法
		Method[] declaredMethods = ljxClass.getDeclaredMethods();
		for (Method declaredMethod : declaredMethods) {
//			System.out.println(declaredMethod);
		}
		// 获取所有公共的public修饰的方法 包含父类中的public方法
		Method[] methods = ljxClass.getMethods();
		for (Method method : methods) {
//			System.out.println(method);
		}
		// 获取指定的方法(只能获取公共的方法)
		Method doSome = ljxClass.getMethod("doSome");
		System.out.println(doSome);
//		Method doSome1 = ljxClass.getMethod("doSome1");
//		System.out.println(doSome1);
//		Method doSome2 = ljxClass.getMethod("doSome2");
//		System.out.println(doSome2);

		// 执行该方法
		doSome.invoke(o);
		System.out.println("'+"+doSome);
	}

}
@Data
@AllArgsConstructor
@NoArgsConstructor
class Ljx{
	public String name;
	public Integer age;
	private int weight;
	String moren;
	protected String soubaohu;

	public void doSome(){
		System.out.println("你好世界");
	}

	private void doSome1(){
		System.out.println("你好世界");
	}

	public void doSome2(int a){
		System.out.println("你好世界");
	}

}
